--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+ creator="GPSBabel - http://www.gpsbabel.org"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://www.topografix.com/GPX/1/0"
+ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<bounds minlat="36.000000000" minlon="-87.000000000" maxlat="36.000000000" maxlon="-87.000000000"/>
+<trk>
+<trkseg>
+<trkpt lat="36.000000000" lon="-87.000000000">
+ <time>2010-05-06T06:00:00Z</time>
+</trkpt>
+<trkpt lat="36.000000000" lon="-87.000000000">
+ <time>2008-04-17T00:00:00Z</time>
+</trkpt>
+<trkpt lat="36.000000000" lon="-87.000000000">
+ <time>2010-05-06T06:00:05Z</time>
+</trkpt>
+</trkseg>
+</trk>
+</gpx>
--- /dev/null
+lat, lon, date
+36, -87
+36, -87, 2008-04-17
+36, -87
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+ creator="GPSBabel - http://www.gpsbabel.org"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://www.topografix.com/GPX/1/0"
+ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<bounds minlat="36.000000000" minlon="-87.000000000" maxlat="36.000000000" maxlon="-87.000000000"/>
+<trk>
+<trkseg>
+<trkpt lat="36.000000000" lon="-87.000000000">
+ <time>2010-05-06T06:00:00Z</time>
+</trkpt>
+<trkpt lat="36.000000000" lon="-87.000000000">
+ <time>2010-05-06T06:00:05Z</time>
+</trkpt>
+<trkpt lat="36.000000000" lon="-87.000000000">
+ <time>2010-05-06T06:00:10Z</time>
+</trkpt>
+</trkseg>
+</trk>
+</gpx>
gpsbabel -t -i vitosmt -f ${REFERENCE}/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt_t.gpx
compare ${TMPDIR}/vitosmt_t.gpx ${REFERENCE}/track/vitosmt_t.gpx
-#
-# tracks filter tests
-#
-
-rm -f ${TMPDIR}/trackfilter*
-
-gpsbabel -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,split,title="LOG-%Y%m%d" -o gpx -F ${TMPDIR}/trackfilter.gpx
-compare ${TMPDIR}/trackfilter.gpx ${REFERENCE}/track/trackfilter.gpx
-
-gpsbabel -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,split,sdistance=0.1k -o gpx -F ${TMPDIR}/trackfilter2.gpx
-compare ${TMPDIR}/trackfilter2.gpx ${REFERENCE}/track/trackfilter-sdistance.gpx
-
-gpsbabel -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,sdistance=0.1k,split=5m,title=%Y%m%d -o gpx -F ${TMPDIR}/trackfilter-sdistance2.gpx
-compare ${TMPDIR}/trackfilter-sdistance2.gpx ${REFERENCE}/track/trackfilter-sdistance2.gpx
-
#
# Map&Guide Motorrad Routenplaner .bcr files test
#
--- /dev/null
+#
+# tracks filter tests
+#
+
+rm -f ${TMPDIR}/trackfilter*
+
+gpsbabel -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,split,title="LOG-%Y%m%d" -o gpx -F ${TMPDIR}/trackfilter.gpx
+compare ${TMPDIR}/trackfilter.gpx ${REFERENCE}/track/trackfilter.gpx
+
+gpsbabel -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,split,sdistance=0.1k -o gpx -F ${TMPDIR}/trackfilter2.gpx
+compare ${TMPDIR}/trackfilter2.gpx ${REFERENCE}/track/trackfilter-sdistance.gpx
+
+gpsbabel -t -i gpx -f ${REFERENCE}/track/trackfilter.gpx -x track,pack,sdistance=0.1k,split=5m,title=%Y%m%d -o gpx -F ${TMPDIR}/trackfilter-sdistance2.gpx
+compare ${TMPDIR}/trackfilter-sdistance2.gpx ${REFERENCE}/track/trackfilter-sdistance2.gpx
+
+# Exercise the 'faketime' filter. The middle of the three points has
+# time so we can exercise the 'forced' option, too.
+gpsbabel -t -i unicsv -f ${REFERENCE}/track/trackfilter_faketime.txt -x track,faketime=20100506060000+5 -o gpx -F ${TMPDIR}/ft.gpx
+compare ${REFERENCE}/track/trackfilter_faketime.gpx ${TMPDIR}/ft.gpx
+gpsbabel -t -i unicsv -f ${REFERENCE}/track/trackfilter_faketime.txt -x track,faketime=f20100506060000+5 -o gpx -F ${TMPDIR}/ftf.gpx
+compare ${REFERENCE}/track/trackfilter_faketime_forced.gpx ${TMPDIR}/ftf.gpx
2007-01-08: if not really needed disable check for valid timestamps
(based on patch from Vladimir Kondratiev)
2007-07-26: Allow 'range' together with trackpoints without timestamp
+ 2010-06-02: Add specified timestamp to each trackpoint (added by sven_luzar)
*/
#include <ctype.h>
#define TRACKFILTER_SPEED_OPTION "speed"
#define TRACKFILTER_SEG2TRK_OPTION "seg2trk"
#define TRACKFILTER_TRK2SEG_OPTION "trk2seg"
+#define TRACKFILTER_FAKETIME_OPTION "faketime"
#undef TRACKF_DBG
static char *opt_name = NULL;
static char *opt_seg2trk = NULL;
static char *opt_trk2seg = NULL;
+static char *opt_faketime = NULL;
static
arglist_t trackfilter_args[] = {
{TRACKFILTER_TRK2SEG_OPTION, &opt_trk2seg,
"Merge tracks inserting segment separators at boundaries",
NULL, ARGTYPE_BOOL, ARG_NOMINMAX },
+ {TRACKFILTER_FAKETIME_OPTION, &opt_faketime,
+ "Add specified timestamp to each trackpoint",
+ NULL, ARGTYPE_STRING, ARG_NOMINMAX},
ARG_TERMINATOR
};
track_ct = 1;
}
+/*******************************************************************************
+* option: "faketime"
+*******************************************************************************/
+
+typedef struct faketime_s
+{
+ time_t start;
+ int step;
+ int force;
+} faketime_t;
+
+static faketime_t
+trackfilter_faketime_check(const char *timestr)
+{
+ int i, j;
+ char fmtstart[20];
+ char fmtstep[20];
+ char c;
+ const char *cin;
+ struct tm time;
+ int timeparse = 1;
+ faketime_t result;
+ result.force = 0;
+
+ i = j = 0;
+ strncpy(fmtstart, "00000101000000", sizeof(fmtstart));
+ strncpy(fmtstep, "00000000000000", sizeof(fmtstep));
+ cin = timestr;
+
+ while ((c = *cin++))
+ {
+ if (c=='f') {
+ result.force = 1;
+ continue;
+ }
+
+ if (c!='+' && isdigit(c) == 0)
+ fatal(MYNAME "-faketime: invalid character \"%c\"!\n", c);
+
+ if (timeparse) {
+ if ((c == '+')) {
+ fmtstart[i++] = '\0';
+ timeparse = 0;
+ } else {
+ if (fmtstart[i] == '\0') fatal(MYNAME "-faketime: parameter too long \"%s\"!\n", timestr);
+ fmtstart[i++] = c;
+ }
+ } else {
+ if (fmtstep[j] == '\0') fatal(MYNAME "-faketime: parameter too long \"%s\"!\n", timestr);
+ fmtstep[j++] = c;
+ }
+ }
+ fmtstep[j++] = '\0';
+
+ cin = strptime(fmtstart, "%Y%m%d%H%M%S", &time);
+ result.step = atoi(fmtstep);
+ if ((cin != NULL) && (*cin != '\0'))
+ fatal(MYNAME "-faketime-check: Invalid time stamp (stopped at %s of %s)!\n", cin, fmtstart);
+
+ result.start = mkgmtime(&time);
+ return result;
+}
+
+static int
+trackfilter_faketime(void) /* returns number of track points left after filtering */
+{
+ faketime_t faketime;
+
+ queue *elem, *tmp;
+ int i, dropped, inside = 0;
+
+ if (opt_faketime != 0)
+ faketime = trackfilter_faketime_check(opt_faketime);
+
+ dropped = inside = 0;
+
+ for (i = 0; i < track_ct; i++)
+ {
+ route_head *track = track_list[i].track;
+
+ QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp)
+ {
+ waypoint *wpt = (waypoint *)elem;
+
+ if (opt_faketime != 0 && (wpt->creation_time == 0 || faketime.force)) {
+ wpt->creation_time = faketime.start;
+ faketime.start += faketime.step;
+ }
+ }
+ }
+
+ return track_pts - dropped;
+}
+
+
/*******************************************************************************
* global cb's
*******************************************************************************/
if ( !opts ) return;
}
+ if ((opt_faketime != NULL))
+ {
+ opts--;
+
+ trackfilter_faketime();
+
+ if (opts == 0) return;
+
+ trackfilter_deinit(); /* reinitialize */
+ trackfilter_init(NULL);
+
+ if (track_ct == 0) return; /* no more track(s), no more fun */
+ }
+
if ((opt_stop != NULL) || (opt_start != NULL))
{
if (opt_start != NULL) opts--;
--- /dev/null
+<para>
+This option assigns a time value to each trackpoint.
+</para>
+<para>
+The value of this option must be in the form of fYYYYMMDDHHMMSS+SS.
+</para>
+<para>
+The parameter f (force) is optional and means that the time value of each trackpoint is replaced.
+If f is not specified, the time value of each trackpoint is only replaced when the trackpoint contains no time value.
+</para>
+<para>
+YYYYMMDDHHMMSS is the pattern for the timestamp and is required.
+</para>
+<para>
+The plus sign is the delimiter between the timestamp and the step time in seconds.
+The first trackpoint receives the time value of the timestamp and
+each following trackpoint receives the timestamp incremented by the step time.
+The specification of the steptime is optional.
+</para>
+<para>
+The parameter was added because some software products (e.g. garmin training center)
+require a time value for each trackpoint.
+</para>
+<example id="ex_track_faketime1">
+<title>Replace time values of a track</title>
+<para>
+Replace all time values with new time values.
+Start at the 5 th of July, 2010 at 8 PM and
+increment 2 seconds between each trackpoint:
+</para>
+<para><userinput>gpsbabel -i kml -f in.kml -x track,faketime=f20100705200000+2 -o gtrnctr -F out.tcx</userinput></para>
+</example>
+<example id="ex_track_faketime2">
+<title>Add time values to a track</title>
+<para>
+Add a time value to a trackpoint, if the trackpoint contains no time value.
+Start at the 6 th of May, 2010 at 6 AM and
+increment 5 seconds between each trackpoint:
+</para>
+<para><userinput>gpsbabel -i kml -f in.kml -x track,faketime=20100506060000+5 -o gtrnctr -F out.tcx</userinput></para>
+</example>